"""
GUI 应用性能分析示例
演示如何在 PySide6/PyQt 应用中使用 cProfile
"""
import cProfile
import pstats
import io
from typing import Optional
from functools import wraps


# ============================================================================
# 方法 1: 分析事件处理函数
# ============================================================================
def profile_event_handler(func):
    """事件处理函数性能分析装饰器"""
    @wraps(func)
    def wrapper(*args, **kwargs):
        profiler = cProfile.Profile()
        profiler.enable()
        
        try:
            result = func(*args, **kwargs)
        finally:
            profiler.disable()
            
            # 只在调试模式下打印
            if hasattr(args[0], '_debug_mode') and args[0]._debug_mode:
                stats = pstats.Stats(profiler)
                print(f"\n性能分析: {func.__name__}")
                print("-" * 60)
                stats.sort_stats('cumulative').print_stats(10)
        
        return result
    return wrapper


# ============================================================================
# 示例 GUI 类（不依赖 Qt，演示概念）
# ============================================================================
class SimulatedGUIApp:
    """模拟的 GUI 应用"""
    
    def __init__(self):
        self._debug_mode = True  # 开启调试模式
        self.data = []
    
    @profile_event_handler
    def on_button_click(self):
        """模拟按钮点击事件"""
        print("处理按钮点击...")
        # 模拟数据处理
        self.data = [i ** 2 for i in range(10000)]
        return sum(self.data)
    
    @profile_event_handler
    def on_table_load(self):
        """模拟表格加载事件"""
        print("加载表格数据...")
        # 模拟数据加载
        data = []
        for i in range(100):
            row = {'id': i, 'value': i ** 2, 'text': f'Item {i}'}
            data.append(row)
        return data
    
    @profile_event_handler
    def on_filter_changed(self, filter_text: str):
        """模拟过滤变更事件"""
        print(f"过滤: {filter_text}")
        # 模拟过滤操作
        result = [item for item in self.data if str(item).find(filter_text) >= 0]
        return result


# ============================================================================
# 方法 2: 使用上下文管理器分析代码段
# ============================================================================
class ProfileSection:
    """代码段性能分析上下文管理器"""
    
    def __init__(self, section_name: str, enable: bool = True):
        self.section_name = section_name
        self.enable = enable
        self.profiler: Optional[cProfile.Profile] = None
    
    def __enter__(self):
        if self.enable:
            self.profiler = cProfile.Profile()
            self.profiler.enable()
        return self
    
    def __exit__(self, exc_type, exc_val, exc_tb):
        if self.enable and self.profiler:
            self.profiler.disable()
            self.print_stats()
    
    def print_stats(self, limit: int = 10):
        """打印统计信息"""
        if not self.profiler:
            return
        
        stats = pstats.Stats(self.profiler)
        print(f"\n性能分析: {self.section_name}")
        print("-" * 60)
        stats.sort_stats('cumulative').print_stats(limit)


def example_gui_with_context():
    """使用上下文管理器分析 GUI 代码"""
    print("\n" + "=" * 60)
    print("示例: GUI 代码段分析")
    print("=" * 60)
    
    # 模拟初始化阶段
    with ProfileSection("初始化阶段"):
        data = [{'id': i, 'name': f'Item {i}'} for i in range(1000)]
    
    # 模拟渲染阶段
    with ProfileSection("渲染阶段"):
        html = '<table>'
        for item in data:
            html += f"<tr><td>{item['id']}</td><td>{item['name']}</td></tr>"
        html += '</table>'
    
    # 模拟用户交互阶段
    with ProfileSection("用户交互"):
        filtered = [item for item in data if item['id'] % 2 == 0]
        sorted_data = sorted(filtered, key=lambda x: x['name'])


# ============================================================================
# 方法 3: 性能监控类
# ============================================================================
class PerformanceMonitor:
    """GUI 应用性能监控器"""
    
    def __init__(self):
        self.profiles = {}
        self.enabled = True
    
    def profile_method(self, method_name: str):
        """方法性能分析装饰器"""
        def decorator(func):
            @wraps(func)
            def wrapper(*args, **kwargs):
                if not self.enabled:
                    return func(*args, **kwargs)
                
                profiler = cProfile.Profile()
                profiler.enable()
                
                try:
                    result = func(*args, **kwargs)
                finally:
                    profiler.disable()
                    
                    # 保存分析结果
                    if method_name not in self.profiles:
                        self.profiles[method_name] = []
                    self.profiles[method_name].append(profiler)
                
                return result
            return wrapper
        return decorator
    
    def get_summary(self, method_name: str) -> str:
        """获取方法的性能摘要"""
        if method_name not in self.profiles:
            return f"没有 {method_name} 的性能数据"
        
        s = io.StringIO()
        s.write(f"\n性能摘要: {method_name}\n")
        s.write(f"调用次数: {len(self.profiles[method_name])}\n")
        s.write("-" * 60 + "\n")
        
        # 合并所有分析结果
        combined_stats = pstats.Stats(self.profiles[method_name][0], stream=s)
        for profiler in self.profiles[method_name][1:]:
            combined_stats.add(profiler)
        
        combined_stats.sort_stats('cumulative').print_stats(10)
        
        return s.getvalue()
    
    def clear(self):
        """清除所有分析数据"""
        self.profiles.clear()


# 使用示例
monitor = PerformanceMonitor()


class MonitoredApp:
    """带性能监控的应用"""
    
    @monitor.profile_method('load_data')
    def load_data(self, count: int):
        """加载数据"""
        return [i ** 2 for i in range(count)]
    
    @monitor.profile_method('process_data')
    def process_data(self, data):
        """处理数据"""
        return sum(data) / len(data) if data else 0
    
    @monitor.profile_method('render_ui')
    def render_ui(self, data):
        """渲染UI"""
        result = []
        for item in data:
            result.append(f"<div>{item}</div>")
        return '\n'.join(result)


def example_performance_monitor():
    """性能监控器示例"""
    print("\n" + "=" * 60)
    print("示例: 性能监控器")
    print("=" * 60)
    
    app = MonitoredApp()
    
    # 模拟多次调用
    for i in range(5):
        data = app.load_data(1000 * (i + 1))
        avg = app.process_data(data)
        html = app.render_ui(data[:10])  # 只渲染前10项
    
    # 打印性能摘要
    print(monitor.get_summary('load_data'))
    print(monitor.get_summary('process_data'))
    print(monitor.get_summary('render_ui'))


# ============================================================================
# 方法 4: 热点函数识别
# ============================================================================
class HotspotAnalyzer:
    """热点函数分析器"""
    
    def __init__(self, threshold: float = 0.01):
        self.threshold = threshold  # 时间阈值（秒）
        self.profiler = cProfile.Profile()
    
    def start(self):
        """开始分析"""
        self.profiler.enable()
    
    def stop(self):
        """停止分析"""
        self.profiler.disable()
    
    def get_hotspots(self) -> list:
        """获取热点函数列表"""
        stats = pstats.Stats(self.profiler)
        hotspots = []
        
        for func, (cc, nc, tt, ct, callers) in stats.stats.items():
            if ct > self.threshold:  # 累计时间超过阈值
                hotspots.append({
                    'function': f"{func[2]} ({func[0]}:{func[1]})",
                    'cumtime': ct,
                    'tottime': tt,
                    'ncalls': nc
                })
        
        # 按累计时间排序
        hotspots.sort(key=lambda x: x['cumtime'], reverse=True)
        return hotspots
    
    def print_hotspots(self, limit: int = 10):
        """打印热点函数"""
        hotspots = self.get_hotspots()
        
        print("\n热点函数分析:")
        print("-" * 80)
        print(f"{'函数':<50} {'累计时间':<15} {'调用次数':<10}")
        print("-" * 80)
        
        for i, hotspot in enumerate(hotspots[:limit], 1):
            print(f"{i}. {hotspot['function']:<48} "
                  f"{hotspot['cumtime']:<15.6f} {hotspot['ncalls']:<10}")


def example_hotspot_analysis():
    """热点函数分析示例"""
    print("\n" + "=" * 60)
    print("示例: 热点函数分析")
    print("=" * 60)
    
    analyzer = HotspotAnalyzer(threshold=0.001)
    
    analyzer.start()
    
    # 模拟各种操作
    app = MonitoredApp()
    data = app.load_data(5000)
    avg = app.process_data(data)
    html = app.render_ui(data[:100])
    
    analyzer.stop()
    analyzer.print_hotspots()


# ============================================================================
# 主函数
# ============================================================================
def run_all_examples():
    """运行所有 GUI 性能分析示例"""
    print("GUI 应用性能分析示例")
    print("=" * 80)
    
    # 示例 1: 装饰器方式
    print("\n示例 1: 事件处理函数分析")
    print("=" * 60)
    app = SimulatedGUIApp()
    app.on_button_click()
    app.on_table_load()
    app.on_filter_changed("100")
    
    # 示例 2: 上下文管理器
    example_gui_with_context()
    
    # 示例 3: 性能监控器
    example_performance_monitor()
    
    # 示例 4: 热点分析
    example_hotspot_analysis()


if __name__ == '__main__':
    run_all_examples()
